package cn.fz.ssedemo.exception;

import cn.fz.ssedemo.domain.vo.ResultVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;

/**
 * 统一异常处理类
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(BizException.class)
    public ResultVO<String> handleBusinessException(BizException bx) {
        log.error("接口调用业务异常信息{}", bx.getMessage());
        // 返回统一处理类
        return ResultVO.failed(bx.getMessage());
    }

    /**
     * 捕获 {@code ParamException} 异常
     */
    @ExceptionHandler(ParamException.class)
    public ResultVO<String> paramExceptionHandler(ParamException ex) {
        log.error("接口调用异常：ParamException, 异常信息{}", ex.getMessage());
        // 返回统一处理类
        return ResultVO.failed(ex.getMessage());
    }

    /**
     * 顶级异常捕获并统一处理，当其他异常无法处理时候选择使用
     */
    @ExceptionHandler(Exception.class)
    public ResultVO<String> handle(Exception ex) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        ex.printStackTrace(pw);
        // msg就是最后取出来的字符串,可存数据库
        log.error("接口调用异常：{}", sw);
        // 返回统一处理类
        return ResultVO.failed("服务器500错误");
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResultVO<String> handleValidationExceptions(MethodArgumentNotValidException ex) {
        List<ObjectError> errors = ex.getBindingResult().getAllErrors();
        StringBuilder errorMsg = new StringBuilder();
        for (ObjectError error : errors) {
            errorMsg.append(error.getDefaultMessage()).append("; ");
        }
        return ResultVO.failed(errorMsg.toString());
    }
}
